home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld Examples / Split-Screen Scrolling / Split-Screen Demo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-19  |  15.1 KB  |  526 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Split-Screen Demo.c
  3. //
  4. // By Vern Jensen. Created 3/8/97
  5. ///--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include <SWFPSReport.h>
  9. #include <SWIncludes.h>
  10. #include <SWGameUtils.h>
  11. #include "SWApplication.h"
  12. #include "Multi-Screen Scrolling.h"
  13.  
  14. #include "Split-Screen Demo.h"
  15. #include "Sprite Stuff.h"
  16.  
  17.  
  18. #define    kInterlacedMode                false        // Turns Interlaced mode on/off
  19. #define kSyncToVBL                    false        // Sync SpriteWorld to VBL?
  20. #define kMaxFPS                        30            // Set to 0 for unrestricted speed
  21. #define kLavaFrameRate                7            // Change lava tile every X frames
  22.  
  23.  
  24.  
  25. /***********/
  26. /* Globals */
  27. /***********/
  28.  
  29. WindowPtr            gWindowP;
  30. SpriteWorldPtr        gMasterSpriteWorldP, gCloneSpriteWorldP;
  31. SpriteLayerPtr        gTankSpriteLayerP, gBulletSpriteLayerP, gPowerUpSpriteLayerP;
  32. TileMapStructPtr    gTileMapStructP;
  33. TileMapPtr            gTileMap;
  34. Rect                gMasterRect, gCloneRect;    // The world rects for each SpriteWorld
  35. Rect                gMoveBoundsRect;
  36. DrawProcPtr            gSpriteMaskDrawProc;
  37. RgnHandle            gTempRgn;                    // Used by TankHitDrawProc
  38.  
  39. KeyStruct            gTank1Keys, gTank2Keys;        // Structures containing keys for each tank
  40.  
  41.  
  42.  
  43.  
  44. ///--------------------------------------------------------------------------------------
  45. // Main
  46. ///--------------------------------------------------------------------------------------
  47.  
  48. void    main( void )
  49. {
  50.     Initialize(kNumberOfMoreMastersCalls);
  51.     
  52.     if (SWHasSystem7())
  53.     {
  54.         gTempRgn = NewRgn();    // Create temp region
  55.         AllowKeyUpEvents();        // Part of SWGameUtils.c
  56.         SetCursor(*GetCursor(watchCursor));
  57.         
  58.         CreateSpriteWorlds();
  59.         LoadSprites();
  60.         CreateTankSprites();
  61.         
  62.         SetCursor(&qd.arrow);
  63.         HideCursor();
  64.         
  65.         SetUpAnimation();
  66.         RunAnimation();
  67.         ShutDown();
  68.         
  69.         DisposeRgn(gTempRgn);    // Dispose temp region
  70.         RestoreEventMask();        // Call this after AllowKeyUpEvents
  71.     }
  72.     else
  73.     {
  74.         CantRunOnThisMachine();
  75.     }
  76. }
  77.  
  78.  
  79. ///--------------------------------------------------------------------------------------
  80. // CreateSpriteWorlds
  81. ///--------------------------------------------------------------------------------------
  82.  
  83. void    CreateSpriteWorlds( void )
  84. {
  85.     Rect        offscreenRect, windRect;
  86.     OSErr        err;
  87.     
  88.     gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  89.     
  90.     if (gWindowP != NULL)
  91.     {
  92.             // Calculate the size of the window
  93.         windRect.top = 0;
  94.         windRect.left = 0;
  95.         windRect.right = qd.screenBits.bounds.right - 20;
  96.         windRect.bottom = qd.screenBits.bounds.bottom / 2;
  97.         
  98.             // Calculate the rects for each SpriteWorld
  99.         gMasterRect = gCloneRect = windRect;
  100.         gMasterRect.right = gMasterRect.right/2 - 15;
  101.         gCloneRect.left = gMasterRect.right + 30;
  102.         
  103.             // Center the window in the screen
  104.         SizeWindow(gWindowP, windRect.right, windRect.bottom, false);
  105.         CenterRect(&windRect, &qd.screenBits.bounds);
  106.         MoveWindow(gWindowP, windRect.left, windRect.top, false);
  107.         
  108.         ShowWindow(gWindowP);
  109.         SetPort(gWindowP);
  110.     }
  111.     else
  112.         CantFindResource();
  113.     
  114.     
  115.     err = SWEnterSpriteWorld();
  116.     FatalError(err);
  117.     
  118.     
  119.         // Set size of offscreen area
  120.     offscreenRect = gMasterRect;
  121.     OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
  122.     
  123.  
  124.         // Make offscreen area evenly divisible by tile width & height
  125.     if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
  126.         offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
  127.     
  128.     if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
  129.         offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
  130.  
  131.     
  132.         // Create the Master SpriteWorld
  133.     err = SWCreateSpriteWorldFromWindow(&gMasterSpriteWorldP, (CWindowPtr)gWindowP, 
  134.             &gMasterRect, &offscreenRect, 0);
  135.     FatalError(err);
  136.     
  137.         // Create the Clone SpriteWorld
  138.     err = SWCreateSpriteWorldFromWindow(&gCloneSpriteWorldP, (CWindowPtr)gWindowP, 
  139.             &gCloneRect, &offscreenRect, 0);
  140.     FatalError(err);
  141.     
  142.     
  143.         // Init Tiling for the Master SpriteWorld
  144.     err = SWInitTiling(gMasterSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
  145.     FatalError(err);
  146.     
  147.         // Init Tiling for the Clone SpriteWorld
  148.     err = SWInitTilingForDuplicateSpriteWorld(gCloneSpriteWorldP, kTileHeight, kTileWidth);
  149.     FatalError(err);
  150.     
  151.     
  152.     err = SWLoadTileMap(&gTileMapStructP, 128);
  153.     FatalError(err);
  154.     
  155.     SWInstallTileMap(gMasterSpriteWorldP, gTileMapStructP, 0);
  156.     gTileMap = gTileMapStructP->tileMap;
  157.     
  158.     
  159.         // Load wall tiles
  160.     err = SWLoadTilesFromPictResource(
  161.         gMasterSpriteWorldP, 
  162.         kFirstWallTile,            // startTileID 
  163.         kLastWallTile,            // endTileID
  164.         200,                    // pictResID
  165.         0,                        // maskResID
  166.         kNoMask,                // maskType
  167.         0,                        // horizBorderWidth
  168.         0);                        // vertBorderHeight
  169.     FatalError(err);
  170.     
  171.         // Load floor tiles
  172.     err = SWLoadTilesFromPictResource(
  173.         gMasterSpriteWorldP, 
  174.         kFirstFloorTile,        // startTileID 
  175.         kMudTile,                // endTileID
  176.         201,                    // pictResID
  177.         0,                        // maskResID
  178.         kNoMask,                // maskType
  179.         0,                        // horizBorderWidth
  180.         0);                        // vertBorderHeight
  181.     FatalError(err);
  182.     
  183.         // Load lava tiles
  184.     err = SWLoadTilesFromPictResource(
  185.         gMasterSpriteWorldP, 
  186.         kFirstLavaTile,            // startTileID 
  187.         kLastLavaTile,            // endTileID
  188.         202,                    // pictResID
  189.         0,                        // maskResID
  190.         kNoMask,                // maskType
  191.         0,                        // horizBorderWidth
  192.         0);                        // vertBorderHeight
  193.     FatalError(err);
  194.  
  195.         // Create the sprite layers
  196.     err = SWCreateSpriteLayer(&gPowerUpSpriteLayerP);
  197.     FatalError(err);
  198.     err = SWCreateSpriteLayer(&gBulletSpriteLayerP);
  199.     FatalError(err);
  200.     err = SWCreateSpriteLayer(&gTankSpriteLayerP);
  201.     FatalError(err);
  202.     
  203.         // Add them to the Master SpriteWorld
  204.     SWAddSpriteLayer(gMasterSpriteWorldP, gPowerUpSpriteLayerP);    // Bottom layer
  205.     SWAddSpriteLayer(gMasterSpriteWorldP, gBulletSpriteLayerP);        // Middle layer
  206.     SWAddSpriteLayer(gMasterSpriteWorldP, gTankSpriteLayerP);        // Top layer
  207.     
  208.         // Lock both SpriteWorlds
  209.     SWLockSpriteWorld(gMasterSpriteWorldP);
  210.     SWLockSpriteWorld(gCloneSpriteWorldP);
  211.  
  212.     
  213.         // Set the gSpriteMaskDrawProc before loading sprites
  214.     if (gMasterSpriteWorldP->pixelDepth == 8)
  215.     {
  216.         gSpriteMaskDrawProc = CompiledSprite8BitDrawProc;
  217.     }
  218.     else if ( !(SW_PPC && gMasterSpriteWorldP->pixelDepth < 8) )
  219.     {
  220.         if (kInterlacedMode)
  221.             gSpriteMaskDrawProc = BPAllBitInterlacedMaskDrawProc;
  222.         else
  223.             gSpriteMaskDrawProc = BlitPixieAllBitMaskDrawProc;
  224.     }
  225.     else
  226.     {
  227.         gSpriteMaskDrawProc = SWStdSpriteDrawProc;
  228.     }
  229.  
  230.     SetRect(&gMoveBoundsRect, 0,0, 
  231.         gMasterSpriteWorldP->tileLayerArray[0]->numCols * kTileWidth,
  232.         gMasterSpriteWorldP->tileLayerArray[0]->numRows * kTileHeight);
  233.     SWSetScrollingWorldMoveBounds(gMasterSpriteWorldP, &gMoveBoundsRect);
  234. }
  235.  
  236.  
  237. ///--------------------------------------------------------------------------------------
  238. // CreateTankSprites
  239. ///--------------------------------------------------------------------------------------
  240.  
  241. void    CreateTankSprites( void )
  242. {
  243.     SpritePtr        mySpriteP;
  244.     TankStructPtr    tankStructP;
  245.     
  246.         // Create the sprite on the left
  247.     mySpriteP = NewTankSprite(kPlayer1);
  248.     tankStructP = (TankStructPtr)mySpriteP;
  249.     
  250.     SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.left + 120, gMoveBoundsRect.top + 100);
  251.     SWSetScrollingWorldMoveProc(gMasterSpriteWorldP, ScrollingWorldMoveProc, mySpriteP);
  252.     
  253.         // Create the sprite on the right
  254.     mySpriteP = NewTankSprite(kPlayer2);
  255.     tankStructP = (TankStructPtr)mySpriteP;
  256.     
  257.     SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.right-140, gMoveBoundsRect.bottom-140);
  258.     SWSetScrollingWorldMoveProc(gCloneSpriteWorldP, ScrollingWorldMoveProc, mySpriteP);
  259.     
  260.         // Create the power-up sprites
  261.     mySpriteP = NewPowerUpSprite(kMachineGun);
  262.     SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.right - 140, gMoveBoundsRect.top + 120);
  263.  
  264.     mySpriteP = NewPowerUpSprite(kMachineGun);
  265.     SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.left + 130, gMoveBoundsRect.bottom - 160);
  266. }
  267.  
  268.  
  269. ///--------------------------------------------------------------------------------------
  270. // SetUpAnimation
  271. ///--------------------------------------------------------------------------------------
  272.  
  273. void    SetUpAnimation( void )
  274. {
  275.     SWSetSpriteWorldMaxFPS(gMasterSpriteWorldP, kMaxFPS);
  276.     SWSyncSpriteWorldToVBL(gMasterSpriteWorldP, kSyncToVBL);
  277.     SWSetCleanUpSpriteWorld(gMasterSpriteWorldP);
  278.     
  279.     SWSetTileChangeProc(gMasterSpriteWorldP, TileChangeProc);
  280.     
  281.         // Move visScrollRect to starting sprite position
  282.     SWMoveVisScrollRect(gMasterSpriteWorldP, 
  283.         gMasterSpriteWorldP->followSpriteP->destFrameRect.left - gMasterSpriteWorldP->backRect.right/2,
  284.         gMasterSpriteWorldP->followSpriteP->destFrameRect.top - gMasterSpriteWorldP->backRect.bottom/2);
  285.     
  286.     
  287.         // Set the various DrawProcs
  288.     if (gMasterSpriteWorldP->pixelDepth == 8)        // If in 256 colors
  289.     {
  290.         if (kInterlacedMode)
  291.         {
  292.             SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BP8BitInterlacedRectDrawProc);
  293.             SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BP8BitInterlacedRectDrawProc);
  294.             SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BP8BitInterlacedDoubleRectDrawProc);
  295.         }
  296.         else
  297.         {
  298.             SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BlitPixie8BitRectDrawProc);
  299.             SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BlitPixie8BitRectDrawProc);
  300.             SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BlitPixie8BitDoubleRectDrawProc);
  301.         }
  302.     }
  303.     else if ( !(SW_PPC && gMasterSpriteWorldP->pixelDepth < 8) )    // Not 256 colors
  304.     {
  305.         if (kInterlacedMode && gMasterSpriteWorldP->pixelDepth != 1)
  306.         {
  307.                 // Use interlaced drawProcs unless in B&W, where interlacing is ugly
  308.             SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  309.             SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  310.             if (gMasterSpriteWorldP->pixelDepth == 16)
  311.                 SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BP16BitInterlacedDoubleRectDrawProc);
  312.         }
  313.         else
  314.         {
  315.             SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BlitPixieAllBitRectDrawProc);
  316.             SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BlitPixieAllBitRectDrawProc);
  317.             if (gMasterSpriteWorldP->pixelDepth == 16)
  318.                 SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BlitPixie16BitDoubleRectDrawProc);
  319.         }
  320.     }
  321.     
  322.         // Make sure CopyBits, if used, doesn't try to colorize things
  323.     SWSetPortToWindow(gMasterSpriteWorldP);
  324.     ForeColor(blackColor);
  325.     BackColor(whiteColor);
  326.     
  327.     
  328.         // Copy information from the Master SpriteWorld to the Clone SpriteWorld
  329.     SWSetUpDuplicateSpriteWorld(gMasterSpriteWorldP, gCloneSpriteWorldP);
  330.     
  331.     
  332.     SWDrawTilesInBackground(gMasterSpriteWorldP);
  333.     SWDrawTilesInBackground(gCloneSpriteWorldP);
  334.     SWUpdateScrollingSpriteWorld(gMasterSpriteWorldP, true);
  335.     SWUpdateScrollingSpriteWorld(gCloneSpriteWorldP, true);
  336. }
  337.  
  338.  
  339. ///--------------------------------------------------------------------------------------
  340. //  RunAnimation
  341. ///--------------------------------------------------------------------------------------
  342.  
  343. void    RunAnimation( void )
  344. {
  345.     unsigned long        frames;
  346.     
  347.     frames = 0;
  348.     StartTimer();
  349.     
  350.     FatalError( SWStickyError() );    // Make sure no errors got past us during setup
  351.     
  352.     while (!Button())
  353.     {
  354.         UpdateKeys();
  355.         SWProcessSpriteWorld(gMasterSpriteWorldP);
  356.         
  357.         if (gMasterSpriteWorldP->frameHasOccurred)
  358.         {
  359.             SWProcessMultiScreenSpriteWorld(gMasterSpriteWorldP);
  360.             SWProcessMultiScreenSpriteWorld(gCloneSpriteWorldP);
  361.             
  362.             SWCollideSpriteLayer(gMasterSpriteWorldP, gBulletSpriteLayerP, gTankSpriteLayerP);
  363.             SWCollideSpriteLayer(gMasterSpriteWorldP, gPowerUpSpriteLayerP, gTankSpriteLayerP);
  364.             
  365.                 // Make sure no errors occurred during a MoveProc, etc.
  366.             FatalError( SWStickyError() );
  367.             
  368.             SWAnimateMultiScreenSpriteWorld(gMasterSpriteWorldP);
  369.             SWAnimateMultiScreenSpriteWorld(gCloneSpriteWorldP);
  370.             SWFinishMultiScreenAnimation(gMasterSpriteWorldP);
  371.             
  372.             frames++;
  373.         }
  374.     }
  375.     
  376.     ShowResults(frames);
  377. }
  378.  
  379.  
  380. ///--------------------------------------------------------------------------------------
  381. //  ShutDown (clean up and dispose of the SpriteWorlds)
  382. ///--------------------------------------------------------------------------------------
  383.  
  384. void    ShutDown( void )
  385. {
  386.     SWDisposeDuplicateSpriteWorld(gCloneSpriteWorldP);
  387.     SWDisposeSpriteWorld(&gMasterSpriteWorldP);
  388.     SWExitSpriteWorld();
  389.     
  390.     FlushEvents(everyEvent, 0);
  391.     ShowCursor();
  392. }
  393.  
  394.  
  395. ///--------------------------------------------------------------------------------------
  396. //  TileChangeProc
  397. ///--------------------------------------------------------------------------------------
  398.  
  399. SW_FUNC void TileChangeProc(
  400.     SpriteWorldPtr spriteWorldP)
  401. {
  402.     short            curImage;
  403.     static short    wallDelay = 0, oldTicks = 0;
  404.     static short    direction = 1;
  405.     short            ticksPassed, ticks;
  406.     
  407.         // Initialize oldTicks the first time this function is called
  408.     if (oldTicks == 0)
  409.         oldTicks = TickCount();
  410.     
  411.     ticks = TickCount();
  412.     ticksPassed = ticks - oldTicks;        // Number of ticks passed since last call
  413.     oldTicks = ticks;
  414.     
  415.         // kWallTile
  416.     wallDelay += ticksPassed;
  417.     if (wallDelay >= kLavaFrameRate)
  418.     {
  419.         curImage = spriteWorldP->curTileImage[kFirstLavaTile];
  420.         
  421.             // Cycling mode
  422.         if (curImage < kLastLavaTile)
  423.             curImage++;
  424.         else
  425.         {
  426.             curImage = kFirstLavaTile;
  427.         }
  428.     
  429.         
  430. /*            // Patrolling mode
  431.         if (curImage == kLastLavaTile && direction > 0)
  432.             direction = -1;
  433.         else if (curImage == kFirstLavaTile && direction < 0)
  434.             direction = 1;
  435.         
  436.         curImage += direction;
  437. */        
  438.         
  439.         SWChangeTileImage(gMasterSpriteWorldP, kFirstLavaTile, curImage);
  440.         SWChangeTileImage(gCloneSpriteWorldP, kFirstLavaTile, curImage);
  441.         wallDelay = 0;
  442.     }
  443. }
  444.  
  445.  
  446. ///--------------------------------------------------------------------------------------
  447. //  ScrollingWorldMoveProc
  448. ///--------------------------------------------------------------------------------------
  449.  
  450. SW_FUNC void ScrollingWorldMoveProc(
  451.     SpriteWorldPtr spriteWorldP,
  452.     SpritePtr followSpriteP)
  453. {    
  454.     short    screenWidth, screenHeight, spriteWidth, spriteHeight;
  455.     short    horizPos, vertPos;
  456.     
  457.     screenWidth = (spriteWorldP->visScrollRect.right - spriteWorldP->visScrollRect.left);
  458.     screenHeight = (spriteWorldP->visScrollRect.bottom - spriteWorldP->visScrollRect.top);
  459.     spriteWidth = (followSpriteP->destFrameRect.right - followSpriteP->destFrameRect.left);
  460.     spriteHeight = (followSpriteP->destFrameRect.bottom - followSpriteP->destFrameRect.top);
  461.     
  462.     horizPos = followSpriteP->destFrameRect.left + spriteWidth/2 - screenWidth/2;
  463.     vertPos = followSpriteP->destFrameRect.top + spriteHeight/2 - screenHeight/2;
  464.     
  465.     if (kInterlacedMode)
  466.         vertPos = vertPos>>1<<1;
  467.     
  468.     SWMoveVisScrollRect(spriteWorldP, horizPos, vertPos);
  469. }
  470.  
  471.  
  472. ///--------------------------------------------------------------------------------------
  473. //  UpdateKeys (Put the latest key values in the gKeys structure)
  474. ///--------------------------------------------------------------------------------------
  475.  
  476. void    UpdateKeys( void )
  477. {
  478.     EventRecord        event;
  479.     short            theKey;
  480.     Boolean            isDown;
  481.     
  482.     while ( GetOSEvent( (keyUpMask | keyDownMask), &event ) )
  483.     {
  484.         theKey = (event.message & keyCodeMask) >> 8;
  485.         isDown = (event.what != keyUp);
  486.         
  487.         switch (theKey)
  488.         {
  489.                 // Tank 1 keys
  490.             case kLeftPlayer1Key:
  491.                 gTank1Keys.left = isDown;
  492.                 break;
  493.             case kRightPlayer1Key:
  494.                 gTank1Keys.right = isDown;
  495.                 break;
  496.             case kDownPlayer1Key:
  497.                 gTank1Keys.down = isDown;
  498.                 break;
  499.             case kUpPlayer1Key:
  500.                 gTank1Keys.up = isDown;
  501.                 break;
  502.             case kShootPlayer1Key:
  503.                 gTank1Keys.shoot = isDown;
  504.                 break;
  505.             
  506.                 // Tank 2 keys
  507.             case kLeftKeyPad:
  508.                 gTank2Keys.left = isDown;
  509.                 break;
  510.             case kRightKeyPad:
  511.                 gTank2Keys.right = isDown;
  512.                 break;
  513.             case kDownKeyPad:
  514.                 gTank2Keys.down = isDown;
  515.                 break;
  516.             case kUpKeyPad:
  517.                 gTank2Keys.up = isDown;
  518.                 break;
  519.             case kShootKeyPad:
  520.                 gTank2Keys.shoot = isDown;
  521.                 break;
  522.         }
  523.     }
  524. }
  525.  
  526.